﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    public class MenuitemRepository : BaseRepository<TMenu>, IMenuitemRepository
    {
        public MenuitemRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }


        /// <summary>
        /// 根据用户id查询该用户的所有权限
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<UserRoleMenuAction> GetMenuitemAction(int uid)
        {
            var urlist = Context.TUserRoles.Where(x => x.UserId == uid).Select(x => x.RoleId).Distinct();

            var rmalist = Context.TRoleMenuActions.AsQueryable();

            var list = (from ur in urlist
                        join rma in rmalist
                        on ur equals rma.RoleId
                        group rma by rma.MenuId into g
                        select new UserRoleMenuAction
                        {
                            mid = g.Key,
                            aids = g.Select(x => x.ActionId).ToList()
                        }).ToList();

            return list;
        }


        /// <summary>
        /// 获取菜单列表
        /// </summary>
        /// <param name="mname"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public List<MenuDto> GetMenuList(string mname, int status)
        {
            try
            {
                var mlist = Context.TMenus.AsQueryable();
                if(!string.IsNullOrEmpty(mname))
                {
                    mlist = mlist.Where(x => x.MenuName.Contains(mname));
                }
                if(status!=2)
                {
                    mlist = mlist.Where(x => x.Status == status);
                }
                //List<MenuDto> llist = new List<MenuDto>();
                //foreach (var item in mlist.ToList())
                //{
                //    if(item.ParentId==0)
                //    {
                //       llist=GetMenuLists(mlist.ToList(), 0);
                //    }
                //    llist = GetMenuLists(mlist.ToList(), (int)item.ParentId);
                //}
                if (mlist.Any())
                {
                    mlist = mlist.OrderBy(x => x.ParentId);
                    var mmlist = mlist.FirstOrDefault();
                    return GetMenuLists(mlist.ToList(), mmlist.ParentId.GetValueOrDefault());                 
                }
                var list = GetMenuLists(mlist.ToList(), 0);
                return list;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 递归显示菜单列表
        /// </summary>
        /// <param name="list"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        public static List<MenuDto> GetMenuLists(List<TMenu> list,int pid)
        {
            try
            {
                return list.Where(x => x.ParentId == pid).Select(x => new MenuDto
                {
                    id = x.Id,
                    ParentId = x.ParentId,
                    MenuUrl = x.MenuUrl,
                    Meta = new MetaDto
                    { 
                        MenuName = x.MenuName,
                        MenuIcon = x.MenuIcon,
                    },
                    Status=x.Status,
                    DisplayOrder=x.DisplayOrder,
                    children = GetMenuLists(list, x.Id)
                }).OrderBy(x=>x.DisplayOrder).ToList();
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 左侧穿梭框显示
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        public List<TAction> GetLeftMenuActionList(int mid)
        {
            try
            {
                var missingButtons = Context.TActions
     .Where(b => !Context.TMenuActions.Any(r => r.MenuId == mid && r.ActionId == b.Id))
     .ToList();
                return missingButtons;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 添加菜单操作关系
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMenuAction(TMenuAction m)
        {
            //使用事务的原子性
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    var menuaction = Context.TMenuActions.Where(x => x.MenuId == m.MenuId);
                    if(menuaction!=null)
                    {
                        Context.RemoveRange(menuaction);
                    }
                    if(string.IsNullOrEmpty(m.ActionIds))
                    {
                        var mobj = Context.TMenuActions.FirstOrDefault(x=>x.MenuId==m.MenuId);
                        if (mobj!=null)
                        {
                            Context.TMenuActions.Remove(mobj);
                            Context.SaveChanges();
                            tran.Commit();
                            return true;
                        }
                        return false;
                    }
                    foreach (var menu in m.ActionIds.Split(',')) 
                    {
                        TMenuAction ma= new TMenuAction();
                        ma.MenuId = m.MenuId;
                        ma.ActionId=Convert.ToInt32(menu);
                        Context.TMenuActions.Add(ma);
                        Context.SaveChanges();
                    }
                    
                    tran.Commit();
                    return true;
                }
                catch (Exception)
                {
                    //事务回滚
                    tran.Rollback();
                    throw;
                }
            }
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool DelMenuItem(int mid)
        {
            try
            {
                //判断菜单表是否为空
                var mobj = Context.TMenus.Find(mid);
                if (mobj != null)
                {
                    //删除菜单
                    Context.TMenus.Remove(mobj);
                    //查询角色菜单操作中该角色拥有的所有权限并删除
                    var rma = Context.TRoleMenuActions.Where(x => x.MenuId == mid);
                    Context.TRoleMenuActions.RemoveRange(rma);
                    //查询菜单操作关系表并删除
                    var rw = Context.TMenuActions.Where(x => x.MenuId == mid);
                    Context.RemoveRange(rw);
                }
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMenuItem(TMenu m)
        {
            try
            {
                //var mobj = Context.TMenus.FirstOrDefault(x => x.MenuName == m.MenuName);
                //if(mobj!=null)
                //{
                //    return false;
                //}
                m.CreateUserId = m.NowUserId;
                m.CreateUserName = m.NowUserRealName;
                m.ModifyUserId = m.NowUserId;
                m.ModifyUserName = m.NowUserRealName;
                m.CreateDate = DateTime.Now;
                m.ModifyDate = DateTime.Now;
                Context.TMenus.Add(m);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="M"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdMenuItem(TMenu m)
        {
            try
            {          
                m.ModifyDate = DateTime.Now;
                m.ModifyUserId = m.NowUserId;
                m.ModifyUserName = m.NowUserRealName;

                Context.TMenus.Update(m);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 右侧穿梭框显示
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        public List<TAction> GetRightMenuActionList(int mid)
        {
            try
            {
                var mlist = Context.TMenuActions.AsQueryable();
                var alist = Context.TActions.AsQueryable();
                var list = (from a in mlist
                            join b in alist
                            on a.ActionId equals b.Id
                            where a.MenuId == mid
                            select b).Distinct();
                return list.ToList();
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 加载分配权限列表
        /// </summary>
        /// <param name="rid">角色Id</param>
        /// <returns></returns>
        public List<MenuRoleMenuActionDto> GetMenuActionList(int rid)
        {
            //所有菜单
            var mlist = Context.TMenus.AsQueryable();
            //角色菜单按钮关系
            var rmalist = Context.TRoleMenuActions.AsQueryable();
            //菜单和按钮的关系
            var malist = Context.TMenuActions.AsQueryable();
            //所有按钮
            var alist = Context.TActions.AsQueryable();

            //递归获取所有菜单
            return GetMenuDtoList(mlist.ToList(), malist.ToList(), alist.ToList(), rmalist.ToList(), 0, rid);
        }

        /// <summary>
        /// 递归获取所有菜单
        /// </summary>
        /// <param name="list">菜单列表</param>
        /// <param name="malist">菜单按钮表</param>
        /// <param name="alist">按钮表</param>
        /// <param name="rmalist">角色菜单按钮关系表</param>
        /// <param name="pid">父级Id</param>
        /// <param name="rid">角色Id</param>
        /// <returns></returns>
        public static List<MenuRoleMenuActionDto> GetMenuDtoList(List<TMenu> list, List<TMenuAction> malist, List<TAction> alist, List<TRoleMenuAction> rmalist, int pid, int rid)
        {
            var menuDtoList = new List<MenuRoleMenuActionDto>();

            foreach (var menu in list.Where(x => x.ParentId == pid))
            {
                var menuDto = new MenuRoleMenuActionDto
                {
                    //Id
                    id = menu.Id,
                    //父级Id
                    ParentId = menu.ParentId,
                    //路径
                    MenuUrl = menu.MenuUrl,
                    Meta = new MetaDto
                    {
                        //菜单名称
                        MenuName = menu.MenuName,
                        //菜单图标
                        MenuIcon = menu.MenuIcon,
                    },
                    //状态
                    Status = menu.Status,
                    //排序编号
                    DisplayOrder = menu.DisplayOrder
                };

                var children = GetMenuDtoList(list, malist, alist, rmalist, menu.Id, rid);

                if (children.Count > 0)
                {
                    menuDto.children = children;
                }
                else
                {
                    var actionDtoList = GetActionDtoList(malist, alist, menu.Id, rmalist, rid);

                    if (actionDtoList.Count > 0)
                    {
                        menuDto.Action = actionDtoList;
                    }
                }

                menuDto.IsChecked = GetRoleMenuDtoList(rmalist, rid, menu.Id);

                menuDtoList.Add(menuDto);
            }

            return menuDtoList.OrderBy(x => x.DisplayOrder).ToList();
        }

        /// <summary>
        /// 递归获取该菜单所拥有的按钮
        /// </summary>
        /// <param name="malist">菜单按钮表</param>
        /// <param name="alist">按钮表</param>
        /// <param name="mid">菜单Id</param>
        /// <param name="rmalist">角色菜单按钮关系表</param>
        /// <param name="rid">角色Id</param>
        /// <returns></returns>
        public static List<ActionDto> GetActionDtoList(List<TMenuAction> malist, List<TAction> alist, int mid, List<TRoleMenuAction> rmalist, int rid)
        {
            var actionDtoList = new List<ActionDto>();

            foreach (var menuAction in malist.Where(x => x.MenuId == mid))
            {
                var action = alist.FirstOrDefault(x => x.Id == menuAction.ActionId);

                if (action != null)
                {
                    actionDtoList.Add(new ActionDto
                    {
                        Id = action.Id,
                        ActionName = action.ActionName,
                        IsChecked = GetRoleActionDtoList(rmalist, rid, mid, action.Id)
                    });
                }
            }

            return actionDtoList;
        }

        /// <summary>
        /// 判断该角色是否拥有该菜单权限
        /// </summary>
        /// <param name="rmalist">角色菜单按钮关系表</param>
        /// <param name="rid">角色Id</param>
        /// <param name="mid">菜单Id</param>
        /// <returns></returns>
        public static bool GetRoleMenuDtoList(List<TRoleMenuAction> rmalist, int rid, int mid)
        {
            return rmalist.Any(x => x.RoleId == rid && x.MenuId == mid);
        }

        /// <summary>
        /// 判断该角色在该菜单中是否拥有按钮权限
        /// </summary>
        /// <param name="rmalist">角色菜单按钮关系表</param>
        /// <param name="rid">角色Id</param>
        /// <param name="mid">菜单Id</param>
        /// <param name="aid">按钮Id</param>
        /// <returns></returns>
        public static bool GetRoleActionDtoList(List<TRoleMenuAction> rmalist, int rid, int mid, int aid)
        {
            return rmalist.Any(x => x.RoleId == rid && x.MenuId == mid && x.ActionId == aid);
        }

        /// <summary>
        /// 分配权限
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public bool AddRoleMenuAction(CRoleMenuAction m)
        {
            var rmalist = Context.TRoleMenuActions.Where(x => x.RoleId == m.Rid);

            if (rmalist.Any())
            {
                Context.TRoleMenuActions.RemoveRange(rmalist);
            }

            foreach (var item in m.MidArr)
            {
                var actionIds = item.Aids.Split(',').Select(aid => Convert.ToInt32(aid));

                foreach (var actionId in actionIds)
                {
                    var rma = new TRoleMenuAction
                    {
                        RoleId = m.Rid,
                        MenuId = item.Mid,
                        ActionId = actionId
                    };

                    Context.TRoleMenuActions.Add(rma);
                }
            }
            return Context.SaveChanges() > 0;
        }  
    }
}
